<?php

namespace App\Service;

use App\Models\Base\LogVipSignRole;
use App\Models\Base\Order;
use App\Models\Base\StatPlayer;
use App\Models\Game\PlayerGamedata;
use App\Models\Login\Account;
use Carbon\Carbon;
use Illuminate\Support\Collection;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Log;

/**
 * 玩家逻辑代码
 */
class PlayerService
{
    /**
     * [$delivery 多少的倍数插入,其它更新,一小时写入一条数据].
     *
     * @var int
     */
    protected $delivery = 12;

    /**
     * [getOnlinePlayerNum 获取玩家当前在线数量].
     *
     * @Author   王文凡
     * @DateTime 2018-03-07
     *
     * @version  1.0
     *
     * @return object
     */
    public static function getOnlinePlayerNum()
    {
        $db = DB::reconnect('mysql_game')->table('player_gamedata');
        $number = $db->where('isOnline', 1)->where('platformID', '!=', 99)->get()->count();

        return $number;
    }

    /**
     * [saveLocalPlayerNum 写入本地统计玩家在线数量].
     *
     * @Author   王文凡
     * @DateTime 2018-04-28
     *
     * @version  1.0
     *
     * @param [type] $server_id [游戏服]
     * @param [type] $num       [在线数量]
     *
     * @return [type] [description]
     */
    public static function saveLocalPlayerNum($server_id, $num)
    {
        $date_time = CarBon::today()->toDateString();
        $hour = Carbon::now()->subHours(1)->format('H');
        if (23 == $hour) {
            $date_time = Carbon::yesterday()->toDateString();
        }
        $data = [
            'server_id' => $server_id,
            'online_number' => $num,
            'hour' => $hour,
            'date_time' => $date_time,
        ];

        return StatPlayer::create($data);
    }

    /**
     * [getNewPlayerNum 当日新增人数].
     *
     * @Author   王文凡
     * @DateTime 2018-03-07
     *
     * @version  1.0
     *
     * @return [type] [description]
     */
    public static function NewPlayer()
    {
        //当日时间戳
        $today = Carbon::today()->timestamp;
        $player = Account::where('ac_createTime', '>=', "{$today}")->get();

        return $player;
    }

    /**
     * 某一时段新增角色.
     *
     * @param string $start_at
     * @param string $end_at
     *
     * @return mixed
     */
    public static function someDayNewRole($start_at, $end_at)
    {
        $db = DB::reconnect('mysql_game');

        return $db->table('player_gamedata')->whereBetween('registerTime', [$start_at, $end_at])->get();
    }

    /**
     * [todayOnlineTopTime 获取当天每个时段在线人数].
     *
     * @Author   王文凡
     * @DateTime 2018-03-07
     *
     * @version  1.0
     *
     * @return [type] [description]
     */
    public static function todayOnlineTime()
    {
        $date_time = CarBon::today()->toDateString();
        $data = StatPlayer::where('date_time', $date_time)->selectRaw('hour,sum(online_number) as number')
            ->groupBy('hour')->get();

        return $data;
    }

    /**
     * [todayOnlineTopTime 当天在线最高峰时段].
     *
     * @Author   王文凡
     * @DateTime 2018-03-07
     *
     * @version  1.0
     *
     * @param array $data todayOnlineTime方法结果集
     *
     * @return [type] [description]
     */
    public static function todayOnlineTopTime($data = '')
    {
        if (false == $data->isEmpty()) {
            $maxValue = $data[0]->number;
            $hour = $data[0]->hour;
            foreach ($data as $key => $value) {
                if ($value->number > $maxValue) {
                    $maxValue = $value->number;
                    $hour = $value->hour;
                }
            }

            return $hour;
        } else {
            return null;
        }
    }

    /**
     * [onlineAvgNum 时段平均人数].
     *
     * @Author   王文凡
     * @DateTime 2018-03-07
     *
     * @version  1.0
     *
     * @param array $data todayOnlineTime方法结果集
     *
     * @return [type] [description]
     */
    public static function onlineAvgNum($data = '')
    {
        if ($data) {
            $data = $data->toArray();
            $count = count($data);

            $totnum = array_sum(array_column($data, 'number'));

            return $totnum ? round($totnum / $count) : 0;
        } else {
            return 0;
        }
    }

    /**
     * [getPayerInfo 获取角色信息].
     *
     * @Author   王文凡
     * @DateTime 2018-04-02
     *
     * @version  1.0
     *
     * @param [type] $server_id [服务器id]
     * @param [type] $plyer_id  [角色id]
     *
     * @return [type] [description]
     */
    public static function getPayerInfo($server_id, $player_id)
    {
        setDB($server_id);
        $db = DB::reconnect('mysql_game');

        return $db->table('player_gamedata')->where('id', "{$player_id}")->where('platformID', '!=', 99)->first();
    }

    /**
     * [getTodayPlayerNum 获取某一天玩家数量].
     *
     * @Author   王文凡
     * @DateTime 2018-04-21
     *
     * @version  1.0
     *
     * @param string $day [日期]
     *
     * @return Collection
     */
    public static function getTodayPlayerNum($start_at, $end_at)
    {
        $db = DB::reconnect('mysql_game');

        return $db->table('player_gamedata')->whereBetween('registerTime', [$start_at, $end_at])->where('platformID','!=', 99)->get();
    }

    /**
     * [getSignPlayer 时间段内创建的角色].
     *
     * @Author   王文凡
     * @DateTime 2018-05-08
     *
     * @version  1.0
     *
     * @param int $start_at
     * @param int $end_at
     *
     * @return mixed
     */
    public static function getSignPlayer($start_at, $end_at, $channel_id = null)
    {
        $db = DB::reconnect('mysql_game');
        $db = $db->table('player_gamedata')->where('platformID', '!=', 99)->whereBetween('registerTime', [$start_at, $end_at]);
        if (null !== $channel_id) {
            $db = $db->where('channelId', $channel_id);
        }

        return $db->get();
    }

    /**
     * [PlayerOnlineCount 区间在线的玩家].
     *
     * @Author   王文凡
     * @DateTime 2018-05-08
     *
     * @version  1.0
     *
     * @param string $start_at   [description]
     * @param string $end_at     [description]
     * @param int    $channel_id
     *
     * @return int
     */
    public static function sometimeLoginPlayer($start_at, $end_at, $channel_id = null)
    {
        $db = DB::reconnect('mysql_game_log');
        $db = $db->table('log_player_login')->whereBetween('time', [$start_at, $end_at])
            ->where('flag', 1);
        if (null !== $channel_id) {
            $db->where('channelId', $channel_id);
        }

        return $db->groupBy('playerid')->get();
    }

    /**获取玩家装备
     * @param $player_id
     * @return array
     */
    public static function getPlayerEquipment($player_id)
    {
        $data = PlayerGamedata::find($player_id);
        $equip = binary_to_term($data->partDataArray);
        $equip_data = $equip[0][4];
        $array = [];
        foreach ($equip_data as $key => $value) {
            if (is_array($value)) {
                foreach ($value as $v) {
                    if (is_array($v)) {
                        $array[] = $v;
                    }
                }
            }
        }

        return $array;
    }

    /**
     * 玩家称号列表.
     *
     * @param $player_id
     */
    public static function getPlayerTitleList($player_id)
    {
        $data = PlayerGamedata::find($player_id);
        $titleList = binary_to_term($data->titleList);
        dd($titleList);
    }

    /**
     * 区服玩家在线统计
     *
     * @param $date_time
     * @param $server_id
     *
     * @return mixed
     */
    public static function onlineNumber($date_time, $server_id)
    {
        $ret = StatPlayer::select(
            DB::Raw('sum(online_number) as numbers')
        )
            ->where('date_time', $date_time)
            ->where('server_id', $server_id)->get();

        return $ret;
    }

    /**
     * 根据角色ID获取某一时段登陆数量.
     *
     * @param $start_at
     * @param $end_at
     * @param $ids
     *
     * @return mixed
     */
    public static function playerLoginCount($start_at, $end_at, $ids)
    {
        $db = DB::reconnect('mysql_game_log');
        $count = $db->table('log_player_login')->whereBetween('time', [$start_at, $end_at])
            ->where('flag', 1)->where('platformid', '!=', 99)
            ->whereIn('playerid', $ids)->groupBy('playerid')->get();

        return $count;
    }

    /**
     * 某一天vip角色.
     *
     * @param string $date
     * @param int    $server_id
     *
     * @return Collection|null
     */
    public static function somedayLoginVipRole($date, $server_id)
    {
        return LogVipSignRole::where('date_time', $date)->where('server_id', $server_id)->get();
    }

    /**
     * 获取所有付费用户信息.
     *
     * @param null $channel_id
     *
     * @return Collection|null
     */
    public static function getPayUserInfo($channel_id = null)
    {
        $db = DB::reconnect('mysql_game');
        $db = $db->table('player_gamedata')->where('platformID', '!=', 99)->where('totaltreasure', '>', 0);
        if (null !== $channel_id) {
            $db->where('channelId', $channel_id);
        }

        return $db->get();
    }

    /**
     * 用户最后一次充值记录.
     *
     * @param $role_id
     *
     * @return Collection|null
     */
    public static function roleLastPayInfo($role_id)
    {
        return Order::where('player_id', $role_id)->orderBy('id', 'desc')->first();
    }

    /**
     * 玩家充值天数.
     *
     * @param $role_id
     *
     * @return int
     */
    public static function rolePayDays($role_id)
    {
        return Order::where('player_id', "{$role_id}")->selectRaw("DATE_FORMAT(created_at,'%Y-%m-%d') as date_time")
            ->groupBy('date_time')->get()->count();
    }

    /**
     * 玩家登录天数.
     *
     * @param $role_id
     *
     * @return int
     */
    public static function roleLoginDays($role_id)
    {
        $db = DB::reconnect('mysql_game_log');
        $count = $db->table('log_player_login')
            ->where('flag', 1)->where('platformid', '!=', 99)
            ->where('playerid', "$role_id")->groupBy('playerid')->get()->count();

        return $count;
    }

    /**
     * 玩家最后一次登录记录.
     *
     * @param $role_id
     *
     * @return Collection
     */
    public static function roleLastLogin($role_id)
    {
        $db = DB::reconnect('mysql_game_log');
        $data = $db->table('log_player_login')
            ->where('flag', 1)->where('platformid', '!=', 99)
            ->where('playerid', "$role_id")->orderBy('time', 'desc')->first();

        return $data;
    }

    /**
     * 获取某一天之前的注册角色.
     *
     * @param $timestmap
     *
     * @return Collection
     */
    public static function somedayAgoRegisterRole($timestmap)
    {
        $db = DB::reconnect('mysql_game');
        $data = $db->table('player_gamedata')->where('createTime', '<=', $timestmap)
                ->where('platformID', '!=', 99)->get();

        return $data;
    }

    /**
     * 根据玩家id获取流失玩家.
     *
     * @param array $roleIds       注册角色id
     * @param int   $todayTimesmap
     * @param int   $channel_id
     *
     * @return Collection
     */
    public static function getRemainUserByRoleId(array $roleIds, $todayTimesmap, $channel_id = null)
    {
        $db = DB::reconnect('mysql_game');
        $db = $db->table('player_gamedata')->whereNotIn('id', $roleIds)->where('platformID', '!=', 99)
            ->where('createTime', '<', $todayTimesmap);
        if (null !== $channel_id) {
            $db = $db->where('channelId', $channel_id);
        }

        return $db->get();
    }

    /**
     * 给玩家发送邮件.
     *
     * @param array $post
     * @param array $emailItem
     *
     * @return bool
     */
    public static function sendGameMail(array $post, $emailItem)
    {
        $itemData = [];
        if ($emailItem) {
            foreach ($emailItem as $value) {
                if (0 == $value['item_id']) {
                    continue;
                }
                $itemData[] = [
                    'itemDataId' => intval($value['item_id']),
                    'itemCnt' => intval($value['num']),
                    'flag' => intval($value['flag']),
                ];
            }
        }
        //全服发送
        if ($post['recipient_type']) {
            if ($post['level_section']) {
                $level = explode('-', $post['level_section']);
                $min_level = $level[0];
                $max_level = $level[1];
            } else {
                $min_level = $max_level = 0;
            }

            $role_name = '';
            $data = [
                'server_id' => intval($post['server_id']),
                'flag' => intval($post['recipient_type']),
                'low_level' => intval($min_level),
                'high_level' => intval($max_level),
                'mailTitle' => $post['title'],
                'mailContent' => $post['content'],
                'receiveName' => $role_name,
                'receiveID' => '0',
                'itemList' => $itemData,
            ];
           //所有区服发送
            if($post['server_id'] == -1){
                $serverIds = ServerService::serverIds();
                foreach ($serverIds as $serverId){
                    $data['server_id'] = intval($serverId);
                    if (false == RequestService::emailAward($data)) {
                        Log::error('发送邮件失败:', $post);
                        return false;
                    }
                }
            }else{
                if (false == RequestService::emailAward($data)) {
                    Log::error('发送邮件失败:', $post);
                    return false;
                }
            }

        } else {
            setDB($post['server_id']);
            foreach ($post['recipients'] as $player_id) {
                if (null == $player_id) {
                    continue;
                }
                //查询角色名
                $player = PlayerGamedata::find($player_id);
                $role_name = $player->name;
                $data = [
                    'server_id' => intval($post['server_id']),
                    'flag' => intval($post['recipient_type']),
                    'low_level' => 0,
                    'high_level' => 0,
                    'mailTitle' => $post['title'],
                    'mailContent' => $post['content'],
                    'receiveName' => $role_name,
                    'receiveID' => $player_id,
                    'itemList' => $itemData,
                ];
                if (false == RequestService::emailAward($data)) {
                    Log::error('发送邮件失败:', $post);

                    return false;
                }
            }
        }

        return true;
    }

    /**
     * 当前区服等级数量集合.
     *
     * @return mixed
     */
    public static function playerLevelNumber()
    {
        $db = DB::reconnect('mysql_game');
        $data = $db->table('player_gamedata')
            ->selectRaw('level,count(level) as level_number')
            ->where('platformID', '!=', 99)
            ->where('level', '>', 1)->groupBy('level')
            ->get();

        return $data;
    }

    /**
     * 未登录的等级集合.
     *
     * @param int $level
     * @param int $time
     *
     * @return Collection|null
     */
    public static function somedayNotLogin($level, $time)
    {
        $db = DB::reconnect('mysql_game');
        $data = $db->table('player_gamedata')
            ->where('platformID', '!=', 99)
            ->where('level', $level)
            ->where('lastOfflineTime', '<=', $time)
            ->where('isOnline', 0)
            ->get();

        return $data;
    }

    /**
     * 第一步新手.
     *
     * @param array $player_ids
     *
     * @return Collection
     */
    public static function firstNewTask(array $player_ids, $task_id)
    {
        $db = DB::reconnect('mysql_game_log');

        return $db->table('log_player_task')->where('taskid', $task_id)
            ->where('flag', 3)
            ->whereIn('playerid', $player_ids)->get();
    }

    /**
     * 任务进入或完成次数.
     *
     * @param int $taskid
     * @param int $flag
     *
     * @return Collection|null
     */
    public static function taskEnterInfo($taskid, $flag)
    {
        $db = DB::reconnect('mysql_game_log');

        return $db->table('log_player_task')->where('taskid', $taskid)->where('flag', $flag)->get();
    }

    /**
     * 删除角色.
     *
     * @param $server_id
     * @param $role_id
     *
     * @return mixed
     */
    public static function deleteRole($server_id, $role_id)
    {
        setDB($server_id);
        $db = DB::reconnect('mysql_game');
        $data = $db->table('player_gamedata')
            ->where('id', "$role_id")
            ->update(['isDelete' => 1]);

        return $data;
    }
}
